home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src_ansi / ace / c / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-05  |  14.5 KB  |  678 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: miscellaneous functions **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.    Date: 26th October-30th November, 1st-13th December 1991,
  24.    14th,20th-27th January 1992, 
  25.    2nd-17th, 21st-29th February 1992, 
  26.    1st,13th,14th,22nd,23rd March 1992,
  27.    21st,22nd April 1992,
  28.    2nd,3rd,11th,15th,16th May 1992,
  29.    7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.    2nd-8th,14th-19th,26th-29th July 1992,
  31.    1st-3rd,7th,8th,9th August 1992,
  32.    6th,7th,21st,22nd December 1992,
  33.    12th February 1993,
  34.    1st March 1993,
  35.    20th,30th June 1993,
  36.    1st,2nd July 1993,
  37.    26th October 1993,
  38.    14th,16th,17th,24th,25th December 1993,
  39.    2nd,5th,7th-9th,13th,14th January 1994,
  40.    6th,7th,15th,16th,26th,27th February 1994,
  41.    4th,13th,30th April 1994,
  42.    14th,15th May 1994,
  43.    12th,21st,22nd,25th June 1994,
  44.    10th,14th,24th July 1994,
  45.    3rd,22nd August 1994,
  46.    2nd,3rd,10th September 1994,
  47.    6th October 1995
  48.  */
  49.  
  50. #include "acedef.h"
  51. #include <string.h>
  52.  
  53. #ifdef __GNUC__
  54. #define upper( a ) ( a >= 'a' && a <= 'z' ) ? ( a - 'a' + 'A' ) : ( a )
  55.  
  56. char *strupr( char *string )
  57. {
  58.     char *s;
  59.  
  60.     for( s = string; *s; s++ )
  61.         *s = upper( *s );
  62.  
  63.     return string;
  64. }
  65.  
  66. char *strrev( char *string )
  67. {
  68.     char temp;
  69.     int i = 0, ln = strlen( string ), j = ln-1;
  70.  
  71.     for( ; i < j ; i++, j-- )
  72.     {
  73.         temp = string[i];
  74.         string[i] = string[j];
  75.         string[j] = temp;
  76.     }
  77.  
  78.     return string;
  79. }
  80. #endif
  81.  
  82. /* locals */
  83. static char *frame_ptr[] = {"(a4)", "(a5)"};
  84. /*static    struct stat    _dta;         local DTA buffer */
  85. #define ERROR -1
  86. char    _numstr[] = "0123456789ABCDEF";
  87.  
  88. /* externals */
  89. extern BOOL report_errors;
  90. extern int sym;
  91. extern int lastsym;
  92. extern int lev;
  93. extern SHORT shortval;
  94. extern LONG longval;
  95. extern char id[MAXIDSIZE];
  96. extern char ut_id[MAXIDSIZE];
  97. extern char lastline[MAXLINELEN];
  98. extern char string_const_start[7];
  99. extern char string_const_end[4];
  100. extern BOOL have_lparen;
  101. extern BOOL end_of_source;
  102. extern BOOL break_opt;
  103. extern BOOL asm_comments;
  104. extern BOOL error_log;
  105. extern BOOL make_icon;
  106. extern BOOL list_source;
  107. extern BOOL optimise_opt;
  108. extern BOOL wdw_close_opt;
  109. extern BOOL module_opt;
  110. extern FILE *err_log;
  111. extern int idtype[31];
  112. extern long strconstcount;
  113. extern long tempstrcount;
  114. extern long tempshortcount;
  115. extern long templongcount;
  116. extern char tempstrname[80], tempstrlabel[80];
  117. extern char tempshortname[80], tempshortlabel[80];
  118. extern char templongname[80], templonglabel[80];
  119.  
  120. char *ultoa(register unsigned long n,
  121.             register char *buffer,
  122.             register int radix)
  123. {
  124.     register char *p = buffer;
  125.     char *strrev();
  126.  
  127.     do
  128.         {
  129.         *p++ = _numstr[n % radix];    /* grab each digit */
  130.         }
  131.         while((n /= radix) > 0);
  132.     *p = '\0';
  133.     return(strrev(buffer));            /* reverse and return it */
  134. }
  135.  
  136.   
  137. char *ltoa( register long n,
  138.            register char *buffer,
  139.            int radix)
  140. {
  141.     register char *p = buffer;
  142.  
  143.     if (n < 0)
  144.         {
  145.         *p++ = '-';
  146.         n = -n;
  147.         }
  148.     ultoa(n, p, radix);
  149.     return(buffer);
  150. }
  151.  
  152. char *itoa(long n,
  153.            char *buffer,
  154.            int radix)
  155. {
  156.     char *ltoa();
  157.  
  158.     return(ltoa(((long) n), buffer, radix));
  159. }
  160.  
  161. /* redefine ZC's CTRL-C testing function to do nothing 
  162. long 
  163. Chk_Abort ()
  164. {
  165.   return 0;
  166. }
  167. */
  168.  
  169.  
  170. /* functions */
  171. void make_temp_long (void)
  172. {
  173.   /* make a long integer BSS object for temporary storage
  174.      of actual value parameters */
  175.   char numbuf[40], storesize[40];
  176.  
  177.   itoa (templongcount++, numbuf, 10);
  178.   strcpy (templongname, "_templong");
  179.   strcat (templongname, numbuf);
  180.  
  181.   strcpy (templonglabel, templongname);
  182.   strcat (templonglabel, ":\0");
  183.  
  184.   strcpy (storesize, "ds.l 1 ");
  185.   enter_BSS (templonglabel, storesize);
  186. }
  187.  
  188. void make_temp_short (void)
  189. {
  190.   /* make a short integer BSS object for temporary storage
  191.      of actual value parameters */
  192.   char numbuf[40], storesize[40];
  193.  
  194.   itoa (tempshortcount++, numbuf, 10);
  195.   strcpy (tempshortname, "_tempshort");
  196.   strcat (tempshortname, numbuf);
  197.  
  198.   strcpy (tempshortlabel, tempshortname);
  199.   strcat (tempshortlabel, ":\0");
  200.  
  201.   strcpy (storesize, "ds.l 1 ");
  202.   enter_BSS (tempshortlabel, storesize);
  203. }
  204.  
  205. void make_temp_string (void)
  206. {
  207. /* need a unique BSS string store for ALL string functions to prevent 
  208.    overwriting of string data */
  209.   char numbuf[40], sizebuf[40], storesize[40];
  210.  
  211.   itoa (tempstrcount++, numbuf, 10);
  212.   strcpy (tempstrname, "_tempstring");
  213.   strcat (tempstrname, numbuf);
  214.  
  215.   strcpy (tempstrlabel, tempstrname);
  216.   strcat (tempstrlabel, ":\0");
  217.  
  218.   strcpy (storesize, "ds.b ");
  219.   itoa (MAXSTRLEN, sizebuf, 10);
  220.   strcat (storesize, sizebuf);
  221.   enter_BSS (tempstrlabel, storesize);
  222. }
  223.  
  224. void make_string_const (char *string)
  225. {
  226.   char *strbuf, buf[80], strlabel[80], strname[80];
  227.  
  228.   itoa (strconstcount++, buf, 10);
  229.   /* label for DATA section */
  230.   strcpy (strlabel, "_stringconst");
  231.   strcat (strlabel, buf);
  232.   /* name for reference in code */
  233.   strcpy (strname, strlabel);
  234.   /* complete string label */
  235.   strcat (strlabel, ":\0");
  236.   /* actual string constant */
  237.   strbuf = (char *) alloc (strlen (string) + 10, MEMF_ANY);
  238.   /* +10 is for string_const_start/end (9) & '\0' */
  239.   strcpy (strbuf, string_const_start);
  240.   strcat (strbuf, string);
  241.   strcat (strbuf, string_const_end);
  242.   enter_DATA(strlabel, strbuf);
  243.   /*FreeMem(strbuf,strlen(string)+10); */
  244.   /* push its address onto stack */
  245.   gen ("pea", strname, "  ");
  246. }
  247.  
  248. void make_label_from_linenum (int intconst, char *buf)
  249. {
  250. /* turns a line number into a label */
  251.  
  252.   switch (intconst)
  253.     {
  254.     case shortconst:
  255.       sprintf (buf, "_LINE%d", shortval);
  256.       break;
  257.     case longconst:
  258.       sprintf (buf, "_LINE%ld", longval);
  259.       break;
  260.     }
  261. }
  262.  
  263. LONG max_array_ndx (SYM * curr)
  264. {
  265. /* Returns # of linear elements in an array.
  266.    eg: DIM X(10,10) yields 121 elements: 0..10, 0..10 -> 11 * 11 
  267.  */
  268.   int i;
  269.   LONG max = 1;
  270.  
  271.   for (i = curr->dims; i >= 0; i--)
  272.     max *= curr->index[i];
  273.   return (max);
  274. }
  275.  
  276. void push_indices (SYM * curr)
  277. {
  278. /* put array indices onto stack */
  279.   int ndxcount = 0;
  280.  
  281.   if (!have_lparen)
  282.     insymbol ();
  283.   else
  284.     have_lparen = FALSE;    /* don't want to leave this as TRUE, else if
  285.                    push_indices() called from factor() etc, 
  286.                    insymbol() won't be called here! */
  287.   if (sym != lparen)
  288.     _error (14);
  289.   else
  290.     {
  291.       do
  292.     {
  293.       insymbol ();
  294.       make_sure_short (expr ());
  295.       ndxcount++;
  296.     }
  297.       while ((sym == comma) && (ndxcount <= curr->dims));
  298.  
  299.       /* too few indices: comma expected (ndxcount should now be > curr->dims) */
  300.       if (ndxcount <= curr->dims)
  301.     _error (16);
  302.  
  303.       /* too many indices or syntax error */
  304.       if (sym != rparen)
  305.     _error (9);
  306.     }
  307. }
  308.  
  309. void get_abs_ndx (SYM * curr)
  310. {
  311. /* calculate absolute pointer into array from multiple dimensions */
  312.   int i, ndx_mult = 1;
  313.   char mulbuf[40], srcbuf[40];
  314.  
  315.   gen ("moveq", "#0", "d7");
  316.  
  317.   /* pop indices from stack one at a time */
  318.   for (i = curr->dims; i >= 0; i--)
  319.     {
  320.       sprintf (mulbuf, "#%ld", ndx_mult);
  321.  
  322.       gen ("move.w", "(sp)+", "d1");
  323.       gen ("ext.l", "d1", "  ");
  324.       gen ("move.l", "d1", "-(sp)");    /* push next index after coercing to long */
  325.       gen ("move.l", mulbuf, "-(sp)");    /* push cumulative index */
  326.       gen ("jsr", "lmulu", "  ");
  327.       gen ("add.l", "#8", "sp");
  328.  
  329.       gen ("add.l", "d0", "d7");
  330.       ndx_mult *= curr->index[i];
  331.     }
  332.  
  333.   /* mutiply offset by data type size */
  334.   if (curr->type == stringtype)
  335.     {
  336.       /* multiply d7 (containing absolute index) by string element size */
  337.  
  338.       /* #string_element_size */
  339.       sprintf (srcbuf, "#%ld", curr->numconst.longnum);
  340.  
  341.       /* calculate absolute offset */
  342.       gen ("move.l", "d7", "-(sp)");
  343.       gen ("move.l", srcbuf, "-(sp)");
  344.       gen ("jsr", "lmulu", "  ");    /* d7*MAXSTRLEN */
  345.       gen ("add.l", "#8", "sp");
  346.       gen ("move.l", "d0", "d7");
  347.     }
  348.   else if (curr->type == shorttype)
  349.     gen ("lsl.l", "#1", "d7");    /* d7*2 */
  350.   else
  351.     /* long or single */
  352.     gen ("lsl.l", "#2", "d7");    /* d7*4 */
  353.  
  354.   /* unsigned multiplication XREF */
  355.   enter_XREF ("lmulu");
  356. }
  357.  
  358. int push_struct (SYM * item)
  359. {
  360. /* push either the address of 
  361.    a structure variable or the
  362.    value of one of its members.
  363.  */
  364.   SYM *structype;
  365.   char addrbuf[40], absbuf[40], numbuf[40];
  366.   STRUCM *member;
  367.   BOOL found = FALSE;
  368.   int mbr_type = undefined;
  369.  
  370.   insymbol ();
  371.  
  372.   if (sym == memberpointer)
  373.     {
  374.       /* push value of a member */
  375.       structype = item->other;    /* pointer to structure type definition */
  376.  
  377.       insymbol ();
  378.  
  379.       if (sym != ident)
  380.     _error (7);
  381.       else
  382.     {
  383.       /* does member exist? */
  384.       member = structype->structmem->next;
  385.       while ((member != NULL) && (!found))
  386.         {
  387.           if (strcmp (member->name, id) == 0)
  388.         found = TRUE;
  389.           else
  390.         member = member->next;
  391.         }
  392.  
  393.       /* dereference it? */
  394.       if (!found)
  395.         _error (67);    /* not a member! */
  396.       else
  397.         {
  398.           /* save member type */
  399.           mbr_type = member->type;
  400.  
  401.           /* address of structure */
  402.           itoa (-1 * item->address, addrbuf, 10);
  403.           strcat (addrbuf, frame_ptr[lev]);
  404.  
  405.           if (item->shared && lev == ONE)
  406.         {
  407.           gen ("movea.l", addrbuf, "a0");    /* struct variable address */
  408.           gen ("movea.l", "(a0)", "a0");    /* start address of struct */
  409.         }
  410.           else
  411.         gen ("movea.l", addrbuf, "a0");        /* start address of struct */
  412.  
  413.           /* offset from struct start */
  414.           if (mbr_type != stringtype)
  415.         {
  416.           ltoa (member->offset, absbuf, 10);
  417.           strcat (absbuf, "(a0)");
  418.         }
  419.  
  420.           /* push value */
  421.           if (mbr_type == bytetype)
  422.         {
  423.           gen ("move.b", absbuf, "d0");
  424.           gen ("ext.w", "d0", "  ");
  425.           gen ("move.w", "d0", "-(sp)");
  426.           mbr_type = shorttype;        /* byte */
  427.         }
  428.           else if (mbr_type == shorttype)
  429.         gen ("move.w", absbuf, "-(sp)");    /* short */
  430.           else if (mbr_type == stringtype)
  431.         {
  432.           sprintf (numbuf, "#%ld", member->offset);
  433.           gen ("adda.l", numbuf, "a0");
  434.           gen ("move.l", "a0", "-(sp)");    /* push string address */
  435.         }
  436.           else
  437.         gen ("move.l", absbuf, "-(sp)");    /* long, single */
  438.         }
  439.     }
  440.       insymbol ();
  441.       return (mbr_type);
  442.     }
  443.   else
  444.     {
  445.       /* push address of structure */
  446.       itoa (-1 * item->address, addrbuf, 10);
  447.       strcat (addrbuf, frame_ptr[lev]);
  448.  
  449.       if (item->shared && lev == ONE)
  450.     {
  451.       gen ("movea.l", addrbuf, "a0");    /* address of structure variable */
  452.       gen ("move.l", "(a0)", "-(sp)");    /* start address of structure */
  453.     }
  454.       else
  455.     gen ("move.l", addrbuf, "-(sp)");
  456.  
  457.       return (longtype);
  458.     }
  459. }
  460.  
  461. void change_id_type (int newtype)
  462. {
  463.   int i, first, last;
  464.  
  465.   /* 
  466.      ** Change the data type of a range.
  467.      **
  468.      ** Note that "A-_" is acceptable
  469.      ** since ASC("_") > ASC("Z"). 
  470.    */
  471.   do
  472.     {
  473.       insymbol ();
  474.       if (sym == ident)
  475.     first = id[0] - 'A';
  476.       else
  477.     _error (7);
  478.       insymbol ();
  479.       if (sym == minus)
  480.     {
  481.       /* range */
  482.       insymbol ();
  483.       if (sym == ident)
  484.         last = id[0] - 'A';
  485.       else
  486.         _error (7);
  487.       if (first > last)
  488.         _error (31);
  489.       else
  490.         for (i = first; i <= last; i++)
  491.           idtype[i] = newtype;
  492.       insymbol ();
  493.     }
  494.       else
  495.     /* just a single one (letter or underscore) */
  496.     idtype[first] = newtype;
  497.     }
  498.   while (sym == comma);
  499. }
  500.  
  501. void gen_branch (char *branch, char *labname)
  502. {
  503.   char lablabel[MAXIDSIZE + 1], destbuf[3];
  504.  
  505.   /* generate a jsr/jmp instruction */
  506.  
  507.   sprintf (lablabel, "%s:", labname);
  508.  
  509.   if (!exist (lablabel, label))
  510.     strcpy (destbuf, "* ");    /* for later check */
  511.   else
  512.     strcpy (destbuf, "  ");    /* label already defined */
  513.  
  514.   gen (branch, labname, destbuf);
  515. }
  516.  
  517. void assem (void)
  518. {
  519. /* 
  520.    ** ASSEM..END ASSEM -- inline assembly code inclusion.
  521.  */
  522.  
  523.   report_errors = FALSE;    /* suppress "unknown symbol" errors. */
  524.  
  525.   do
  526.     {
  527.       insymbol ();
  528.  
  529.       /* generate code? */
  530.       if (sym == endofline && !end_of_source &&
  531.       lastsym != assemsym)
  532.     gen (lastline, "  ", "  ");
  533.     }
  534.   while (sym != endsym && !end_of_source);
  535.  
  536.   insymbol ();
  537.   if (sym != assemsym)
  538.     _error (73);
  539.   else
  540.     insymbol ();
  541.  
  542.   report_errors = TRUE;
  543. }
  544.  
  545. void parse_option_list (void)
  546. {
  547.   char letter;
  548.   BOOL activate;
  549. /* OPTION <switch>+|-[,<switch>+|-..] */
  550.  
  551.   do
  552.     {
  553.       insymbol ();
  554.  
  555.       if (sym == ident && strlen (ut_id) == 1)
  556.     {
  557.       letter = ut_id[0];
  558.  
  559.       insymbol ();
  560.       if (sym == plus || sym == minus)
  561.         {
  562.           switch (sym)
  563.         {
  564.         case plus:
  565.           activate = TRUE;
  566.           break;
  567.         case minus:
  568.           activate = FALSE;
  569.           break;
  570.         }
  571.  
  572.           switch (letter)
  573.         {
  574.         case 'b':
  575.           break_opt = activate;
  576.           break;
  577.         case 'c':
  578.           asm_comments = activate;
  579.           break;
  580.         case 'E':
  581.           if (activate && !error_log)
  582.             {
  583.               err_log = fopen ("ace.err", "w");
  584.               if (err_log == NULL)
  585.             puts ("Unable to open error log: ace.err!");
  586.               else
  587.             error_log = TRUE;
  588.             }
  589.           else if (!activate && error_log)
  590.             {
  591.               if (err_log)
  592.             {
  593.               fclose (err_log);
  594.               err_log = NULL;
  595.               error_log = FALSE;
  596.             }
  597.               else
  598.             puts ("Error log: ace.err not open!");
  599.             }
  600.           break;
  601.         case 'i':
  602.           make_icon = activate;
  603.           break;
  604.         case 'l':
  605.           list_source = activate;
  606.           break;
  607.         case 'm':
  608.           module_opt = activate;
  609.           break;
  610.         case 'O':
  611.           optimise_opt = activate;
  612.           break;
  613.         case 'w':
  614.           wdw_close_opt = activate;
  615.           break;
  616.  
  617.         default:
  618.           _error (74);
  619.           break;
  620.         }
  621.         }
  622.       else
  623.         _error (74);
  624.     }
  625.       else
  626.     _error (74);        /* compiler directive expected */
  627.  
  628.       insymbol ();
  629.     }
  630.   while (sym == comma);
  631. }
  632.  
  633. void MsgBox (void)
  634. {
  635. /*
  636.    ** MsgBox _statement_.
  637.    **
  638.    **   MSGBOX <message>,<button-text>
  639.    **
  640.    ** See also basfun.c for MsgBox *function*. 
  641.  */
  642.  
  643.   insymbol ();
  644.  
  645.   if (expr () != stringtype)    /* message */
  646.     _error (4);
  647.   else
  648.     {
  649.       if (sym != comma)
  650.     _error (16);
  651.       else
  652.     {
  653.       insymbol ();
  654.       if (expr () != stringtype)    /* response text */
  655.         _error (4);
  656.       else
  657.         {
  658.           /* no second button! (pass NULL) */
  659.           gen ("move.l", "#0", "-(sp)");
  660.  
  661.           /* call the function */
  662.           gen ("jsr", "_sysrequest", "  ");
  663.           gen ("add.l", "#12", "sp");
  664.           enter_XREF ("_sysrequest");
  665.           enter_XREF ("_IntuitionBase");
  666.         }
  667.     }
  668.     }
  669. }
  670.  
  671. long fsize(char *name)
  672. {
  673.     if(access(name, 0x00))
  674. /*        return(_dta.st_size); */
  675.     return(ERROR);
  676. }
  677.  
  678.